package com.ld.common.controller;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSONObject;
import com.ld.shieldsb.common.core.util.StringUtils;
import com.ld.shieldsb.common.web.BaseController;
import com.ld.shieldsb.common.web.BasicService;
import com.ld.shieldsb.common.web.util.Web;
import com.ld.shieldsb.common.web.util.WebUtil;
import com.ld.shieldsb.dao.MySqlBaseDao;

/**
 * 基本Controller
 * 
 * @ClassName ProjectBasicController
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2019年3月13日 下午2:46:46
 * 
 * @param <T>
 */
public class ProjectBasicController<T> extends BaseController {
    public static final MySqlBaseDao BaseDAO = new MySqlBaseDao("db0.");
//    public static final SnowflakeIdWorker ID_WORKER = new SnowflakeIdWorker(0, 1); // ID_WORKER

    @Autowired
    public HttpServletResponse response;
    @Autowired
    public HttpServletRequest request;
    @Autowired
    public HttpSession session;
    @Autowired
    public ServletContext context;
    @Autowired
    public BasicService basicService;

    protected static final String FORWORD = "forward:"; // 转发
    protected static final String REDIRECT = "redirect:"; // 重定向

    public int getInt(String name) {
        return Web.Parameter.getInt(request, name);
    }

    public long getLong(String name) {
        return Web.Parameter.getLong(request, name);
    }

    public String getString(String name) {
        return Web.Parameter.getString(request, name);
    }

    public double getDouble(String name) {
        return Web.Parameter.getDouble(request, name);
    }

    public Date getDate(String name) {
        return Web.Parameter.getDate(request, name);
    }

    /**
     * 根据参数名，返回参数list
     * 
     * @Title getList
     * @author 吕凯
     * @date 2017年3月3日 下午2:27:10
     * @param name
     * @return List<String>
     */
    protected List<String> getList(String name) {
        return Web.Parameter.getList(request, name);
    }

    /**
     * 
     * 根据参数名，返回参数set
     * 
     * @Title getSet
     * @author 吕凯
     * @date 2017年3月3日 下午3:04:23
     * @param name
     * @return Set<String>
     */
    protected Set<String> getSet(String name) {
        return Web.Parameter.getSet(request, name);
    }

    /**
     * 根据参数名，返回参数数组
     * 
     * @Title getArray
     * @author 吕凯
     * @date 2017年3月3日 下午2:28:03
     * @param name
     * @return String[]
     */
    protected String[] getArray(String name) {
        return Web.Parameter.getArray(request, name);
    }

    /**
     * 
     * 为request的设置Attribute
     * 
     * @Title setAttribute
     * @author 吕凯
     * @date 2018年6月21日 下午5:25:25
     * @param name
     * @param obj
     *            void
     */
    public void setAttribute(String name, Object obj) {
        request.setAttribute(name, obj);
    }

    /**
     * 
     * 将request的Parameter设置到Attribute中
     * 
     * @Title setAttributes
     * @author 吕凯
     * @date 2018年6月21日 下午5:25:14 void
     */
    protected void setAttributes() {
        setAttributes(true);
    }

    /**
     * 
     * 将request的Parameter设置到Attribute中,参数处理器的参数也根据设置进行处理
     * 
     * @Title setAttributes
     * @author 吕凯
     * @date 2019年8月31日 上午10:08:00
     * @param recoverDealParam
     *            是否将处理参数处理器的参数还原为原始状态，如equal_name还原为name void
     */
    protected void setAttributes(boolean recoverDealParam) {
        Enumeration<String> names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String paramName = names.nextElement();
            String paramValue = request.getParameter(paramName);
            paramName = Web.Parameter.decrypt(paramName);
            request.setAttribute(paramName, paramValue);
            if (recoverDealParam && Web.Parameter.hasDealParam(paramName)) { // 将参数处理器处理的参数设置设为原始状态
                String dealPrefix = Web.Parameter.getDealParamPrefix(paramName);
                if (StringUtils.isNotEmpty(dealPrefix)) {
                    request.setAttribute(StringUtils.substringAfter(paramName, dealPrefix), paramValue);
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    protected Class<T> getModelClass() {
        return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    /**
     * 跳转404页面
     * 
     * @Title forward404
     * @author 吕凯
     * @date 2020年4月17日 下午2:27:17
     * @param message
     * @throws ServletException
     * @throws IOException
     *             void
     */
    protected Object forward404(String message) throws ServletException, IOException {
        request.setAttribute("path", request.getServletPath());
        request.setAttribute("message", message);
        request.setAttribute("ip", WebUtil.getIpAddr(request));
//        request.setAttribute("error", message); //错误详情
//        return "error/error";
        return forward("error/error");
    }

    /**
     * 跳转页面
     * 
     * @Title forward
     * @author 吕凯
     * @date 2020年4月29日 下午5:03:17
     * @param page
     * @return
     * @throws ServletException
     * @throws IOException
     *             Object
     */
    protected Object forward(String page) throws ServletException, IOException {
        if (page.startsWith("/")) {
            page = page.substring(1);
        }
        if (!page.endsWith(".jsp")) {
            page += ".jsp";
        }
        request.getRequestDispatcher("/WEB-INF/view/" + page).forward(request, response);
        return null;
    }

    /**
     * 返回json格式
     * 
     * @Title returnJson
     * @author 吕凯
     * @date 2020年4月29日 下午5:03:06
     * @param result
     * @return
     * @throws ServletException
     * @throws IOException
     *             Object
     */
    protected Object returnJson(Object result) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=utf-8");
        response.getWriter().print(JSONObject.toJSON(result));
        return null;
    }

}
